#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <algorithm>

// 抽象基类 是所有叶子和组合对象的基类，声明了一些基本的操作方法
class Component {
    public:
    virtual ~Component() = default;

    virtual void operation() const = 0; // 业务操作
    virtual void add(std::shared_ptr<Component> compoent) {} // 添加子组件
    virtual void remove(std::shared_ptr<Component> compoent) {} // 移除子组件
    virtual std::shared_ptr<Component> getChild(int index) const {return nullptr;} // 获取子组件
};

// 叶子类Leaf,实现了Component接口，但不支持添加或移除子组件
class Leaf : public Component {
    public:
    Leaf(const std::string& name) : name_(name) {}
    virtual void operation() const {
        std::cout << "Leaf " << name_ << " operation." << std::endl;
    }
    private:
    std::string name_;
};

// 组合类Composite，实现了Component接口，支持对子组件的管理和递归操作
class Composite : public Component {
    public:
    virtual void operation() const {
        std::cout << "Composite operation." << std::endl;
        for(const auto& child : children_) {
            child->operation(); // 递归调用子组件的操作
        }
    }

    virtual void add(std::shared_ptr<Component> compoent) {
        children_.push_back(compoent); // 添加子组件
    }

    virtual void remove(std::shared_ptr<Component> compoent) {
        children_.erase(std::remove(children_.begin(),children_.end(),compoent),children_.end()); // 移除子组件
    }

    virtual std::shared_ptr<Component> getChild(int index) const {
        if(index >= 0 && index < children_.size()) {
            return children_[index];  // 获取子组件
        }
        return nullptr;
    }   

    private:
    std::vector<std::shared_ptr<Component>> children_;  // 存储子组件
};

int main () {
    std::cout << "hello composite pattern!!!" << std::endl;
    // 创建叶子节点
    auto leaf1 = std::make_shared<Leaf>("Leaf1");
    auto leaf2 = std::make_shared<Leaf>("Leaf2");

    // 创建组合节点
    auto composite = std::make_shared<Composite>();

    // 添加叶子节点到组合节点中
    composite->add(leaf1);
    composite->add(leaf2);

    // 创建更大的组合节点，并添加子组合节点和叶子节点
    auto root = std::make_shared<Composite>();
    root->add(composite);
    root->add(std::make_shared<Leaf>("Leaf3"));

    // 执行组合对象的操作
    root->operation();

    return 0;
}